Skip to content

Adds auth#174

Merged
elliotBraem merged 14 commits intostagingfrom
feat/auth
Jun 12, 2025
Merged

Adds auth#174
elliotBraem merged 14 commits intostagingfrom
feat/auth

Conversation

@elliotBraem
Copy link
Collaborator

@elliotBraem elliotBraem commented Jun 11, 2025

Summary by CodeRabbit

  • New Features

    • Added support for NEAR wallet authentication using the "fastintear" library.
    • Introduced unified authentication context to manage both Web3Auth and NEAR login methods.
    • User menu and wallet login modal now support NEAR wallet actions.
  • Improvements

    • Streamlined authentication state management across the app.
    • Simplified user profile creation and retrieval based on authentication method.
    • Updated UI to reflect authentication changes, including always-enabled curation buttons and visible user menu.
  • Dependency Updates

    • Added "fastintear" and updated "near-sign-verify" to latest versions.
    • Removed deprecated NEAR wallet selector dependencies.
  • Bug Fixes

    • Improved error handling and logging for NEAR wallet authentication.
  • Developer Experience

    • Enhanced type safety and documentation for authentication and NEAR wallet integration.
    • Removed unused scripts and redundant type definitions.

@vercel
Copy link

vercel bot commented Jun 11, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
curatedotfun-app ⬜️ Skipped (Inspect) Jun 12, 2025 10:25am

@coderabbitai
Copy link

coderabbitai bot commented Jun 11, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This update refactors authentication across the application, centralizing state management in a new AuthContext that supports both Web3Auth and NEAR wallet methods. All NEAR wallet selector dependencies are removed, replaced by the "fastintear" library. Components and API hooks are updated to use the new context. Several types and configuration files are added or modified for type safety and environment alignment.

Changes

File(s) Change Summary
apps/api/package.json
apps/app/package.json
Dependency updates: add near-sign-verify, add/remove other dependencies, update versions.
apps/app/index.html Add script tag for "fastintear" from CDN.
apps/app/src/App.tsx Replace NearWalletProvider with Web3AuthProvider, adjust import order, remove wallet selector CSS.
apps/app/src/components/providers/NearWalletProvider.tsx Remove entire NearWalletProvider component and related wallet selector setup.
apps/app/src/components/UserMenu.tsx
apps/app/src/components/WalletLoginModal.tsx
Switch from wallet selector hooks to new near object for NEAR wallet actions.
apps/app/src/components/Header.tsx Enable UserMenu rendering in header and mobile menu.
apps/app/src/components/CreateAccountModal.tsx Refactor to use new useAuth context for authentication state and user info.
apps/app/src/components/BasicInformationForm.tsx Use near.authStatus() to detect NEAR wallet login; update rendering logic.
apps/app/src/components/CurationFormSteps.tsx Remove disabling of buttons based on login/submission state.
apps/app/src/config/index.ts Change NETWORK_ID from "mainnet" to "testnet".
apps/app/src/contexts/AuthContext.tsx Major refactor: implement unified AuthProvider and useAuth hook for authentication state.
apps/app/src/lib/api.ts Refactor all API hooks to use useAuth for authentication and token retrieval.
apps/app/src/lib/near.ts New module: expose global near object, configure with "testnet".
apps/app/src/routes/_layout/profile/index.tsx Switch from useWeb3Auth to useAuth for authentication and profile logic.
apps/app/src/types/auth.ts New: define types/interfaces for authentication context, NEAR details, and user profile.
apps/app/src/types/fastintear.d.ts New: declare global typings for fastintear on window.
apps/app/src/types/web3auth.ts Remove local UserProfile interface, import from validation module.
apps/api/src/app.ts Pass logger to error handler in error callback.
apps/api/src/utils/auth.ts Use nearVerify from near-sign-verify for wallet login token verification.
packages/types/package.json Remove dev script from npm scripts.
packages/types/tsconfig.json Comment out "extends" property, making config standalone.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant App
    participant AuthContext
    participant NEAR (fastintear)
    participant Web3Auth
    participant API

    User->>App: Load app / Interact
    App->>AuthContext: Initialize
    AuthContext->>Web3Auth: Check login status
    AuthContext->>NEAR: Check wallet status
    alt Web3Auth logged in
        AuthContext->>Web3Auth: Get idToken
        AuthContext->>API: Fetch user profile with idToken
    else NEAR wallet logged in
        AuthContext->>NEAR: Get accountId, publicKey
        AuthContext->>API: Fetch user profile with accountId
    end
    App->>AuthContext: Use login/logout/getIdToken
    App->>API: Make authenticated requests using AuthContext token
Loading

Poem

🐇
Goodbye, old wallets, selectors, and keys,
Fastintear now brings NEAR with ease!
Auth flows united, one context to rule,
Web3Auth or NEAR, the bunny stays cool.
Testnet is set, new types in the mix—
Hopping ahead with some magical tricks!


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@elliotBraem
Copy link
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Jun 11, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

🔭 Outside diff range comments (2)
apps/app/src/components/UserMenu.tsx (1)

90-96: ⚠️ Potential issue

near.signOut() must be existence-checked

Same null-safety issue as previous calls.

-    if (signedAccountId) {
-      near.signOut();
+    if (signedAccountId) {
+      near?.signOut?.();
apps/app/src/lib/api.ts (1)

144-153: ⚠️ Potential issue

Critical: Feed deletion lacks authentication!

The authentication code is commented out, allowing unauthenticated feed deletion. This is a serious security vulnerability that must be fixed before deployment.

Apply this fix to implement proper authentication:

 export function useDeleteFeed(feedId: string) {
-  // const { web3auth } = useWeb3Auth();
+  const { getIdToken, isLoggedIn } = useAuth();
+  
   return useMutation({
     mutationFn: async () => {
-      // if (!web3auth) throw new Error("Web3Auth not initialized");
-      // const authResult = await web3auth.authenticateUser();
-      return deleteFeedApi(feedId);
+      if (!isLoggedIn) throw new Error("User not authenticated");
+      const idToken = await getIdToken("delete feed");
+      if (!idToken) throw new Error("Failed to obtain auth token for deleting feed");
+      return deleteFeedApi(feedId, idToken);
     },
   });
 }

Also update the deleteFeedApi function to accept and use the token:

-export async function deleteFeedApi(feedId: string) {
+export async function deleteFeedApi(feedId: string, idToken: string) {
   return fetch(`/api/feeds/${feedId}`, {
     method: "DELETE",
-    // headers: {
-    //   Authorization: `Bearer ${idToken}`,
-    // },
+    headers: {
+      Authorization: `Bearer ${idToken}`,
+    },
   }).then(async (response) => {
🧹 Nitpick comments (3)
apps/api/package.json (1)

60-63: Consider pinning near-sign-verify to an exact version

Caret ranges allow automatic minor/patch upgrades at deploy time, which can be great but occasionally introduce breaking changes in security-sensitive code such as signature verification. If stability is critical, pin to a fixed version and upgrade deliberately.

apps/app/src/config/index.ts (1)

27-27: Make NETWORK_ID env-driven instead of hard-coded

Hard-coding "testnet" bakes the environment into the bundle and forces a code change for every network switch (testnet → mainnet, staging, etc.). Prefer an env var (e.g. PUBLIC_NEAR_NETWORK_ID) with a sensible default:

-export const NETWORK_ID = "testnet";
+export const NETWORK_ID =
+  process.env.PUBLIC_NEAR_NETWORK_ID ?? "testnet";

Keeps the same behaviour locally while allowing configuration via CI/CD.

apps/app/src/components/BasicInformationForm.tsx (1)

81-89: Render condition fails if userInfo is still loading

The condition isLoggedIn && userInfo evaluates to false while getUserInfo is in flight, briefly showing the “login” prompt before the form pops in. Consider adding a dedicated loading state or checking isLoggedIn only.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 79f280d and 463a091.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (23)
  • apps/api/package.json (1 hunks)
  • apps/api/src/app.ts (2 hunks)
  • apps/api/src/utils/auth.ts (2 hunks)
  • apps/app/index.html (1 hunks)
  • apps/app/package.json (2 hunks)
  • apps/app/src/App.tsx (2 hunks)
  • apps/app/src/components/BasicInformationForm.tsx (3 hunks)
  • apps/app/src/components/CreateAccountModal.tsx (4 hunks)
  • apps/app/src/components/CurationFormSteps.tsx (1 hunks)
  • apps/app/src/components/Header.tsx (3 hunks)
  • apps/app/src/components/UserMenu.tsx (3 hunks)
  • apps/app/src/components/WalletLoginModal.tsx (2 hunks)
  • apps/app/src/components/providers/NearWalletProvider.tsx (0 hunks)
  • apps/app/src/config/index.ts (1 hunks)
  • apps/app/src/contexts/AuthContext.tsx (1 hunks)
  • apps/app/src/lib/api.ts (9 hunks)
  • apps/app/src/lib/near.ts (1 hunks)
  • apps/app/src/routes/_layout/profile/index.tsx (2 hunks)
  • apps/app/src/types/auth.ts (1 hunks)
  • apps/app/src/types/fastintear.d.ts (1 hunks)
  • apps/app/src/types/web3auth.ts (1 hunks)
  • packages/types/package.json (0 hunks)
  • packages/types/tsconfig.json (1 hunks)
💤 Files with no reviewable changes (2)
  • packages/types/package.json
  • apps/app/src/components/providers/NearWalletProvider.tsx
🧰 Additional context used
🧬 Code Graph Analysis (8)
apps/api/src/app.ts (1)
apps/api/src/utils/error.ts (1)
  • errorHandler (22-41)
apps/app/src/components/Header.tsx (1)
apps/app/src/components/UserMenu.tsx (1)
  • UserMenu (23-170)
apps/app/src/App.tsx (2)
apps/app/src/contexts/web3auth.tsx (1)
  • Web3AuthProvider (36-417)
apps/app/src/contexts/AuthContext.tsx (1)
  • AuthProvider (27-435)
apps/app/src/components/WalletLoginModal.tsx (1)
apps/app/src/lib/near.ts (1)
  • near (5-5)
apps/app/src/components/BasicInformationForm.tsx (1)
apps/app/src/lib/near.ts (1)
  • near (5-5)
apps/app/src/components/UserMenu.tsx (1)
apps/app/src/lib/near.ts (1)
  • near (5-5)
apps/app/src/routes/_layout/profile/index.tsx (2)
apps/app/src/contexts/AuthContext.tsx (1)
  • useAuth (437-443)
apps/app/src/lib/api.ts (1)
  • useCurrentUserProfile (420-435)
apps/app/src/components/CreateAccountModal.tsx (1)
apps/app/src/contexts/AuthContext.tsx (1)
  • useAuth (437-443)
🪛 GitHub Actions: CI
apps/app/package.json

[error] 1-1: pnpm install failed due to outdated pnpm-lock.yaml. The lockfile is not up to date with package.json dependencies. Use 'pnpm install --no-frozen-lockfile' to bypass this in CI.

🪛 GitHub Actions: Tests
apps/app/package.json

[error] 1-1: pnpm install failed due to outdated pnpm-lock.yaml. The lockfile is not up to date with package.json dependencies. Use 'pnpm install --no-frozen-lockfile' to bypass this in CI.

🪛 Biome (1.9.4)
apps/app/src/contexts/AuthContext.tsx

[error] 301-307: This code is unreachable

... because this statement will return from the function beforehand

(lint/correctness/noUnreachable)

🔇 Additional comments (20)
packages/types/tsconfig.json (1)

2-2: Double-check the removal of the project-level extends

Commenting out the base config isolates this package from shared compiler rules (target, strictness, path aliases, etc.). Make sure every option you rely on is now redeclared locally, otherwise builds may silently diverge from the rest of the monorepo.

apps/api/src/app.ts (1)

11-23: Good improvement – centralised logger now flows into the error handler

Importing the shared logger and injecting it into errorHandler aligns with the new signature and gives richer context to every error log. 👍

apps/app/src/components/Header.tsx (1)

12-13: User menu successfully wired-in – looks good

UserMenu is now rendered in both desktop and mobile headers and the import path is correct. The component accepts an optional className, so using it bare on line 60 and with a custom class on lines 143-145 is fine. No perf or layout regressions spotted.

Also applies to: 60-60, 143-145

apps/app/src/App.tsx (1)

1-1: Provider stack refactor looks correct

Wrapping AuthProvider inside Web3AuthProvider keeps the underlying Web3Auth instance available before consumer hooks run. Import reorder is harmless. ✅

Also applies to: 4-5, 27-32

apps/app/src/types/web3auth.ts (1)

5-5: 👍 Centralised type source looks good

Switching to the validated UserProfile type keeps definitions DRY and consistent.

apps/app/src/routes/_layout/profile/index.tsx (1)

8-16: LGTM – consistent use of new useAuth hook

The route correctly migrates from useWeb3Auth to useAuth, removing redundant initialisation checks.

apps/app/src/types/fastintear.d.ts (1)

1-8: LGTM! Well-structured global type declarations.

The type declarations properly extend the global Window interface to support the fastintear library integration. This provides type safety for accessing window.near and window.$$ throughout the application.

apps/app/src/types/auth.ts (1)

1-43: Well-structured authentication type definitions.

The type definitions provide a comprehensive and type-safe foundation for the unified authentication context. The interfaces are well-documented and cover all necessary authentication states and methods.

apps/app/src/components/CreateAccountModal.tsx (1)

89-94: Clarify how near_public_key is handled in the mutation.

The comment states "near_public_key is now handled by useCreateUserProfile hook", but the mutation call doesn't pass this parameter. This could be confusing for future maintainers.

Please verify that the useCreateUserProfile hook correctly obtains the NEAR public key from the auth context. If so, consider updating the comment to be more explicit:

-        // near_public_key is now handled by useCreateUserProfile hook
+        // near_public_key is obtained from auth context within useCreateUserProfile hook
apps/app/src/contexts/AuthContext.tsx (1)

357-357: 🛠️ Refactor suggestion

Handle NEAR accounts without dots in username extraction.

The code assumes all NEAR account IDs contain a "." character, which might not be true for top-level accounts.

Add a fallback for accounts without dots:

-       const username = nearAccountDetails.accountId.split(".")[0];
+       const username = nearAccountDetails.accountId.includes(".")
+         ? nearAccountDetails.accountId.split(".")[0]
+         : nearAccountDetails.accountId;

Likely an incorrect or invalid review comment.

apps/app/src/lib/api.ts (10)

8-8: LGTM!

Import change correctly reflects the migration from useWeb3Auth to the new useAuth context.


91-98: Proper authentication token handling.

The function now correctly accepts an authentication token as a parameter and uses it in the Authorization header. This separation of concerns is a good practice.


112-124: Robust authentication implementation.

The hook correctly checks authentication status, retrieves the token with a descriptive purpose, and provides clear error messages for debugging.


155-167: Consistent authentication pattern.

The hook properly implements authentication checks and token retrieval, maintaining consistency with other authenticated operations.


420-435: Well-designed authentication handling.

The hook gracefully handles unauthenticated states by returning null and includes the user ID in the query key for proper cache invalidation. The enabled flag prevents unnecessary API calls when not logged in.


574-625: Consistent authentication implementation.

The hook follows the established pattern with proper authentication checks, descriptive error messages, and conditional enabling based on login status.


654-678: Proper authentication pattern applied.

The implementation correctly handles authentication following the established pattern.


680-704: Consistent authentication handling.

The hook correctly implements the authentication pattern used throughout the file.


706-729: Well-implemented with proper guards.

The hook includes both authentication and feedId checks in the enabled flag, preventing unnecessary API calls. The purpose string includes the specific feed ID for better traceability.


358-400:

Details

✅ Verification successful

Complex but necessary authentication flow.

The implementation correctly handles both NEAR wallet and Web3Auth authentication methods to retrieve the public key. This dual-path approach is required for proper NEAR account creation.

Consider verifying that getWeb3AuthNearCredentials is properly implemented and returns the expected public key format:


🏁 Script executed:

#!/bin/bash
# Search for getWeb3AuthNearCredentials implementation
ast-grep --pattern 'getWeb3AuthNearCredentials' -A 10

Length of output: 1580


Authentication flow verified

The dual-path approach correctly covers both NEAR wallet and Web3Auth flows. Verified that getWeb3AuthNearCredentials (in apps/app/src/contexts/AuthContext.tsx lines 323–332) returns a Promise resolving to an object with a publicKey string as expected.

document.documentElement.classList.add("light");
document.documentElement.classList.remove("dark");
</script>
<script src="https://unpkg.com/fastintear@latest/dist/umd/browser.global.js"></script>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Pin the fastintear script to a specific version and load it non-blocking

Loading @latest from an external CDN couples every deploy to an unknown future version and forces a render-blocking request in the document head.

-    <script src="https://unpkg.com/fastintear@latest/dist/umd/browser.global.js"></script>
+    <!-- Pin the version, add SRI + defer to avoid blocking the critical path -->
+    <script
+      src="https://unpkg.com/fastintear@1.2.3/dist/umd/browser.global.js"
+      integrity="sha384-<insert-hash>"
+      crossorigin="anonymous"
+      defer
+    ></script>

• Predictable builds – no surprise breakages when the lib publishes a new major version
• Better performance – defer lets HTML parsing continue
• Security – SRI protects against tampering

(Replace 1.2.3 and the hash with the desired pinned release.)

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<script src="https://unpkg.com/fastintear@latest/dist/umd/browser.global.js"></script>
<!-- Pin the version, add SRI + defer to avoid blocking the critical path -->
<script
src="https://unpkg.com/fastintear@1.2.3/dist/umd/browser.global.js"
integrity="sha384-<insert-hash>"
crossorigin="anonymous"
defer
></script>
🤖 Prompt for AI Agents
In apps/app/index.html at line 39, the script tag loads the fastintear library
using the @latest tag, causing unpredictable builds and blocking HTML parsing.
Replace the version specifier with a fixed version number (e.g., 1.2.3), add the
defer attribute to load the script non-blocking, and include the integrity
attribute with the appropriate SRI hash to ensure security and integrity of the
loaded script.

Comment on lines +48 to +52
"fastintear": "^0.1.6",
"intear-wallet": "^69.0.0",
"lucide-react": "^0.483.0",
"near-api-js": "4.0.4",
"near-sign-verify": "^0.1.3",
"near-sign-verify": "^0.3.5",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

CI is red – lockfile must be regenerated & consider pinning fastintear

‐ The pipeline fails because pnpm-lock.yaml is out of sync with the new deps (fastintear, updated near-sign-verify, exact @tanstack/* versions).
‐ Run pnpm install && pnpm install --fix-lockfile (or --no-frozen-lockfile in CI) and commit the updated lockfile.

Additionally, fastintear is currently <1.0 and could ship breaking changes under the caret range. Consider pinning to an exact patch version until it stabilises.

Also applies to: 75-76

🤖 Prompt for AI Agents
In apps/app/package.json around lines 48 to 52 and also lines 75 to 76, the CI
fails because the pnpm-lock.yaml file is out of sync with the updated
dependencies including fastintear and near-sign-verify. To fix this, run pnpm
install followed by pnpm install --fix-lockfile locally to regenerate and sync
the lockfile, then commit the updated pnpm-lock.yaml. Additionally, change the
fastintear dependency version from a caret range to an exact patch version to
avoid unexpected breaking changes until the package stabilizes.

Comment on lines +1 to +7
if (typeof window.near === "undefined") {
console.error("need to install fastintear");
}

export const near = window.near;

near.config({ networkId: "testnet" });
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

window may be undefined – guard for SSR and avoid calling .config on undefined

Importing this module on the server (SSR, tests) will throw because window is not defined and near might be undefined when you call near.config.

-if (typeof window.near === "undefined") {
-  console.error("need to install fastintear");
-}
-
-export const near = window.near;
-
-near.config({ networkId: "testnet" });
+// Guard for non-browser environments and missing script
+export const near =
+  typeof window !== "undefined" && typeof window.near !== "undefined"
+    ? window.near
+    : undefined;
+
+if (!near) {
+  console.error(
+    "[fastintear] Global `near` object not found. Make sure the script tag is loaded **before** importing `near.ts`.",
+  );
+} else {
+  near.config({ networkId: "testnet" });
+}

This prevents reference errors and keeps the module import-safe in every runtime.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (typeof window.near === "undefined") {
console.error("need to install fastintear");
}
export const near = window.near;
near.config({ networkId: "testnet" });
// Guard for non-browser environments and missing script
export const near =
typeof window !== "undefined" && typeof window.near !== "undefined"
? window.near
: undefined;
if (!near) {
console.error(
"[fastintear] Global `near` object not found. Make sure the script tag is loaded **before** importing `near.ts`.",
);
} else {
near.config({ networkId: "testnet" });
}
🤖 Prompt for AI Agents
In apps/app/src/lib/near.ts around lines 1 to 7, the code assumes `window` and
`window.near` are always defined, which causes errors during server-side
rendering or testing where `window` is undefined. To fix this, add a check to
ensure `window` and `window.near` exist before accessing or calling
`near.config`. Only call `near.config` if `near` is defined, and handle the case
where `window` or `near` is undefined to prevent runtime errors.

Comment on lines 190 to 192
// disabled={!isLoggedIn || isSubmitting}
className="text-sm md:text-base "
>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Unauthenticated users can now submit feeds – likely unintended

The disabled={!isLoggedIn …} checks were commented out, so any visitor can hit “Next” and “Create Feed”.
Unless the API endpoint allows anonymous writes, this will result in 4xx/5xx errors and a broken UX.

Recommend reinstating the guard, but via the new auth context:

import { useAuth } from "../contexts/AuthContext";

const { isLoggedIn } = useAuth();

disabled={!isLoggedIn || isSubmitting}

Also applies to: 198-199


🏁 Script executed:

#!/bin/bash
# Show lines around the commented‐out disabled prop
rg -n "disabled={!isLoggedIn" -A3 -B3 apps/app/src/components/CurationFormSteps.tsx

# Check if useAuth is imported/used in this file
rg -n "useAuth" apps/app/src/components/CurationFormSteps.tsx

# Search for any useAuth usage in components
rg -n "useAuth" apps/app/src/components

Length of output: 1236


Ensure form submission is gated for authenticated users

The disabled={!isLoggedIn || isSubmitting} prop was commented out around lines 190–192 (and similarly at 198–199), allowing any visitor to click “Next”/“Create Feed” and potentially trigger API errors. Please reinstate the guard using the new auth context:

• At the top of apps/app/src/components/CurationFormSteps.tsx, add:

import { useAuth } from "../contexts/AuthContext";

const { isLoggedIn } = useAuth();

• On your form’s button component, restore:

- // disabled={!isLoggedIn || isSubmitting}
+ disabled={!isLoggedIn || isSubmitting}
  className="text-sm md:text-base"
>

This ensures only authenticated users can proceed.

🤖 Prompt for AI Agents
In apps/app/src/components/CurationFormSteps.tsx around lines 190 to 192 and 198
to 199, the disabled prop on the form buttons was commented out, allowing
unauthenticated users to submit the form. To fix this, import useAuth from
"../contexts/AuthContext" at the top of the file, call const { isLoggedIn } =
useAuth() inside the component, and reinstate the disabled prop on the buttons
as disabled={!isLoggedIn || isSubmitting} to prevent unauthenticated
submissions.

Comment on lines 16 to 21
const handleWalletSelect = (chain: "near" | "solana" | "evm") => {
if (chain === "near") {
signIn();
near.requestSignIn();
}
onClose();
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Un-guarded call to near.requestSignIn() risks runtime crash

handleWalletSelect calls near.requestSignIn() without checking that:

  1. near is defined
  2. requestSignIn exists and is a function

A protective pattern avoids white-screen failures for users without the extension / when the CDN is down.

-  if (chain === "near") {
-    near.requestSignIn();
-  }
+  if (chain === "near") {
+    if (!near?.requestSignIn) {
+      console.error("NEAR wallet not initialised – cannot request sign-in");
+      return;
+    }
+    near.requestSignIn();
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleWalletSelect = (chain: "near" | "solana" | "evm") => {
if (chain === "near") {
signIn();
near.requestSignIn();
}
onClose();
};
const handleWalletSelect = (chain: "near" | "solana" | "evm") => {
if (chain === "near") {
if (!near?.requestSignIn) {
console.error("NEAR wallet not initialised – cannot request sign-in");
return;
}
near.requestSignIn();
}
onClose();
};
🤖 Prompt for AI Agents
In apps/app/src/components/WalletLoginModal.tsx around lines 16 to 21, the call
to near.requestSignIn() is unguarded and may cause runtime crashes if near is
undefined or requestSignIn is not a function. To fix this, add a check to ensure
near is defined and near.requestSignIn is a function before calling it. This
will prevent errors for users without the extension or when the CDN is down.

Comment on lines 31 to 33
const signedAccountId = near.accountId();

useEffect(() => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Top-level evaluation of near.accountId() breaks SSR & initial render

const signedAccountId = near.accountId();

  1. Throws if near is undefined (see earlier comment).
  2. Executes only once, so account changes (e.g. user signs in after page load) won’t update the variable – React won’t re-render.

Suggested quick fix:

-const signedAccountId = near.accountId();
+const [signedAccountId, setSignedAccountId] = useState<string | null>(null);

+useEffect(() => {
+  const id = near?.accountId?.() ?? null;
+  setSignedAccountId(id);
+}, [near]);

Better: expose a dedicated React hook from lib/near that subscribes to wallet events.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const signedAccountId = near.accountId();
useEffect(() => {
// Replace the top-level accountId call with state + effect
- const signedAccountId = near.accountId();
+ const [signedAccountId, setSignedAccountId] = useState<string | null>(null);
+ useEffect(() => {
+ const id = near?.accountId?.() ?? null;
+ setSignedAccountId(id);
+ }, [near]);
useEffect(() => {
🤖 Prompt for AI Agents
In apps/app/src/components/UserMenu.tsx around lines 31 to 33, the top-level
call to near.accountId() causes errors if near is undefined and does not update
on account changes, breaking SSR and reactivity. To fix this, remove the direct
call at the top level and instead use a React hook that subscribes to wallet
events to get the current account ID reactively. Ideally, create or use an
existing hook from lib/near that manages subscription to wallet state changes
and returns the current signed account ID, then use that hook inside the
component to trigger re-renders on account changes.

Comment on lines 5 to 7
import { useWeb3Auth } from "../hooks/use-web3-auth";
import { near } from "../lib/near";
import { useAuthStore } from "../store/auth-store";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Mixed auth paradigms create maintenance risk

The file still imports useWeb3Auth while other modules migrated to useAuth. Keeping both systems alive:

  1. Bloats bundle size & cognitive load
  2. Creates divergent sources of truth (isLoggedIn flags may disagree)

Recommend completing the migration here as well.

🤖 Prompt for AI Agents
In apps/app/src/components/BasicInformationForm.tsx around lines 5 to 7, the
file imports and uses the outdated `useWeb3Auth` hook while the rest of the
codebase has migrated to `useAuth`. To fix this, remove the import and usage of
`useWeb3Auth` and replace them with the `useAuth` hook to unify the
authentication approach, reduce bundle size, and avoid conflicting login states.

Comment on lines 34 to +37
const { isLoggedIn, getUserInfo } = useWeb3Auth();
const { showLoginModal } = useAuthStore();
const isWallet = near.authStatus() === "SignedIn";

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Potential crash: near may be undefined

const isWallet = near.authStatus() === "SignedIn";

If near is undefined, this line throws before the component renders.

-const isWallet = near.authStatus() === "SignedIn";
+const isWallet =
+  (near?.authStatus?.() as string | undefined) === "SignedIn";

Optionally memoise this value in a hook that updates on wallet events.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const { isLoggedIn, getUserInfo } = useWeb3Auth();
const { showLoginModal } = useAuthStore();
const isWallet = near.authStatus() === "SignedIn";
const { isLoggedIn, getUserInfo } = useWeb3Auth();
const { showLoginModal } = useAuthStore();
const isWallet =
(near?.authStatus?.() as string | undefined) === "SignedIn";
🤖 Prompt for AI Agents
In apps/app/src/components/BasicInformationForm.tsx around lines 34 to 37, the
code accesses near.authStatus() without checking if near is defined, which can
cause a crash if near is undefined. Fix this by adding a conditional check to
ensure near is defined before calling authStatus(), and optionally memoize the
isWallet value using a React hook that updates on wallet events to avoid
unnecessary recalculations and improve stability.

Comment on lines 126 to 133
try {
payload = await nearVerify(token);
console.log("payload", payload);
loginType = "wallet";
} catch (e) {
console.log(e);
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Critical: Silent error handling could lead to security vulnerabilities.

The current implementation catches and logs errors from nearVerify without re-throwing them. This means failed NEAR wallet token verifications will be silently ignored, and the middleware will continue without setting the JWT payload or login type.

Consider this fix to maintain proper error handling:

      try {
        payload = await nearVerify(token);
        console.log("payload", payload);
        loginType = "wallet";
      } catch (e) {
        console.log(e);
+       throw e; // Re-throw to maintain the existing error flow
      }

Alternatively, if you want to handle both verification methods failing gracefully, consider logging both failures and continuing without setting the JWT payload, but ensure downstream code properly handles the absence of authentication.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try {
payload = await nearVerify(token);
console.log("payload", payload);
loginType = "wallet";
} catch (e) {
console.log(e);
}
}
try {
payload = await nearVerify(token);
console.log("payload", payload);
loginType = "wallet";
} catch (e) {
console.log(e);
throw e; // Re-throw to maintain the existing error flow
}
}
🤖 Prompt for AI Agents
In apps/api/src/utils/auth.ts around lines 126 to 133, the catch block for
nearVerify errors only logs the error without re-throwing or handling it, which
can cause silent failures and security issues. Modify the catch block to either
re-throw the error after logging to stop further processing or implement logic
to handle the absence of a valid payload explicitly, ensuring downstream code
correctly handles unauthenticated requests. This prevents silent ignoring of
failed token verifications.

Comment on lines +299 to +308
} else if (authMethod === "near" && nearAccountDetails?.accountId) {
return nearAccountDetails?.accountId;
return await sign({
signer: near,
recipient: "curatefun.near", // Replace if different
message:
purposeMessage ||
`authentication for ${nearAccountDetails.accountId}`,
});
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Critical: Unreachable code due to early return.

The function returns nearAccountDetails?.accountId on line 300, making the subsequent signing code unreachable. This appears to be unintentional and would prevent proper NEAR authentication tokens from being generated.

Fix the unreachable code by removing the early return:

        } else if (authMethod === "near" && nearAccountDetails?.accountId) {
-         return nearAccountDetails?.accountId;
+         // return nearAccountDetails?.accountId; // Temporary - remove this line
          return await sign({
            signer: near,
            recipient: "curatefun.near", // Replace if different
            message:
              purposeMessage ||
              `authentication for ${nearAccountDetails.accountId}`,
          });

If returning the account ID directly is intentional for now, consider removing the unreachable signing code to avoid confusion.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} else if (authMethod === "near" && nearAccountDetails?.accountId) {
return nearAccountDetails?.accountId;
return await sign({
signer: near,
recipient: "curatefun.near", // Replace if different
message:
purposeMessage ||
`authentication for ${nearAccountDetails.accountId}`,
});
}
} else if (authMethod === "near" && nearAccountDetails?.accountId) {
// return nearAccountDetails?.accountId; // Temporary - remove this line
return await sign({
signer: near,
recipient: "curatefun.near", // Replace if different
message:
purposeMessage ||
`authentication for ${nearAccountDetails.accountId}`,
});
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 301-307: This code is unreachable

... because this statement will return from the function beforehand

(lint/correctness/noUnreachable)

🤖 Prompt for AI Agents
In apps/app/src/contexts/AuthContext.tsx around lines 299 to 308, there is an
early return of nearAccountDetails?.accountId on line 300 that makes the
subsequent signing code unreachable. To fix this, remove the early return
statement so the function proceeds to execute the signing logic and returns the
authentication token as intended. If returning the account ID is currently
desired, then remove the signing code instead to avoid unreachable code.

@elliotBraem elliotBraem merged commit 8d11e53 into staging Jun 12, 2025
3 of 4 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Jun 17, 2025
elliotBraem added a commit that referenced this pull request Jun 20, 2025
* Get basic working (#109)

* Get basic working

* adds rss feeds

* added stablewatch founder and stablecoin intern from messaria as approvers on stablecoins feed

* fixes to config for grants, sui, and telegram channels (#102)

* add query param for selective processing (#103)

* adds query param to process

* add query param for processing

* simplify

* add tags

* Feat: implement frontend leaderboard (#93)

* feat: implement frontend leaderboard

* feat: implement a leaderboard in frontend

* feat: implemented leaderboard

* fix: rebuild implement leaderboard

* fix: prettier

* fix: prettier

* fix: reimplement frontend leaderboard

* fix: implement frontend leaderboard

* approval rate

* sets approval rate and hides curator

---------

Co-authored-by: Elliot Braem <elliot@ejlbraem.com>

* remove tailwind-scrollbar

* added bob to desci feed

* Get basic working

* set .env.example

* nitpicks

---------

Co-authored-by: Elliot Braem <elliot@ejlbraem.com>
Co-authored-by: codingshot <45281667+codingshot@users.noreply.github.com>
Co-authored-by: Elliot Braem <elliot@everything.dev>
Co-authored-by: Louis <112561517+louisdevzz@users.noreply.github.com>

* fix polyfills

* Explore Page (#108)

* Explore Page - commit-1

* Explore Page - commit-2

* explore page - commit-3

* explore page - commit - 4

* explore page - commit - prettier

* explore page responsiveness + code Rabbit Comments

* code Rabbit Comments resolved

* css updates

* css changes 2

* header update + mobile responsive

* conflicts resolved

* Rebase and changes

* Fix fmt

* Header + Explore Page Style (#113)

* Explore Page - commit-1

* Explore Page - commit-2

* explore page - commit-3

* explore page - commit - 4

* explore page - commit - prettier

* explore page responsiveness + code Rabbit Comments

* code Rabbit Comments resolved

* css updates

* css changes 2

* header update + mobile responsive

* conflicts resolved

* Rebase and changes

* Fix fmt

* Header Updates + Web3Auth getUserInfo + Explore Page changes

* fmt

* coderabbit comments resolved

* Profile page (#120)

* Update the FE to have the profile page (header and tabs init)

* Move tabs to it's own component

* Add stats and top badges to overview

* Finish the overview tab

* Update overview page and init content page

* feat(profile-page): add Content and My Feed tags

* feat(profile-page): finish profile page static UI

* refactor: fmt

* [FEATURE] Create Feed Page - DRAFT (#121)

* Curate Engine Step 1

* content-progress-configuration step-1

* Curation Settings Part 2 and 3

* CodeRabbit Comments Resolved + Mobile Responsive

* Responsiveness: empty State, JSON check

---------

Co-authored-by: Elliot Braem <elliot@everything.dev>

* update to main

* fmt

* Feat/submissions page (#127)

* Submissions Page + Feed Page + Mobile Responsiveness

* fixes

* craete-feed authenticated user condition

* fmt

* remove sqlite

---------

Co-authored-by: Elliot Braem <elliot@ejlbraem.com>

* Feed Page Tabs (#130)

* set tanstack routes (#132)

* [Task]: Add connect button to feed page  (#131)

* feat: Add connect button to feed page

* fix: recommit

* added back to stablecoins feed since stablewatch forked their own

* fix packages, update pg, and ignore cloudflare sockets

* fmt

---------

Co-authored-by: ethnclark <ethanclark1310@gmail.com>
Co-authored-by: codingshot <45281667+codingshot@users.noreply.github.com>
Co-authored-by: Elliot Braem <elliot@ejlbraem.com>

* uses prod data

* Update changes to latest staging

* Revert "Update changes to latest staging"

This reverts commit cd12908.

* Fix Sort By Oldest (#136)

* fix: Sort By Oldest

* fix: Sort By Oldest

* fix: Fix RecentSubmissions Sort Order Update

* fix: All feed should be hidden, remove double title

---------

Co-authored-by: vohuunhan1310@gmail.com <ethanclark1310@gmail.com>

* UI fixes (#138)

* UI fixes

* fmt

---------

Co-authored-by: Elliot Braem <elliot@everything.dev>

* Fix: Leaderboard improvements (#140)

* fix: Leaderboard improvements

* fix: fmt

* reorganize

* remove unused

* rename

* clean up

* fmt

---------

Co-authored-by: Elliot Braem <elliot@ejlbraem.com>

* clean up

* wallet wip

* todo

* auth flow, wip

* types clean up

* fix types

* login modal wip

* modals

* controller, service, successful create account

* clean with data, metadata, and pattern, validation, and json schema

* add migration doc

* add activity and delete user

* fix migration

* add seed remote method

* fix naming

* fix script call

* file extension

* remove build schema

* proper build time

* fix Dockerfile

* rsbuild

* Standard Header Component + Responsivenss Fixes (#146)

* Standard Header Component + Responsivenss Fixes

* fmt

* rename Hero

---------

Co-authored-by: Elliot Braem <elliot@ejlbraem.com>

* fix broken link

* don't distribute on staging

* fix path

* env log

* comment out

* railway env

* fix: Profile adjustments (#153)

* fix: Leaderboard improvements

* fix: fmt

* fix: Profile adjustments

* fix: resolve conversation

* Login Modal Fixes (#154)

* Login Modal Fixes

* Resolve Comments

* container

* container fixes

---------

Co-authored-by: Elliot Braem <elliot@everything.dev>

* organize

* fmt

* update feeds (#156)

* Leaderboard width fixes

* feat: save profile image to pinata (#158)

* feat(fe): save profile image to pinata

* fix: fix comment

* Feat Integrate NEAR Solana, Ethereum wallet selection (#159)

* fix: Leaderboard improvements

* fix: fmt

* fix: Profile adjustments

* fix: resolve conversation

* feat: Integrate NEAR wallet selection

* fix: run fmt

* fix: add function create accesstokenpayload use wallet selector near

* fix: resolve conversation

* Feed Submission + Feed Review Page (#160)

* Feed Review Page and Feed Creation

* fmt

* coderabbit comments resolved

* comments resolved

* comments resolved

* reset routeTree

* minor fixes (#164)

* minor fixes

* fmt

* remove node-compile-cache

* reuse user menu

* header clean up

* remove how it works

* clean up

* set submissions at root route

* fmt

* clean

* create is coming soon

* clean up

* user link

* Adds caddyfile and frontend clean up (#165)

* removes serve static from backend

* fmt

* fix build

* adds caddyfile

* clean up submission feed

* pnpm lock

* fix turbo

* fix build

* db migration

* without time zone

* cleans up submission list

* Adds shared-db, types package, initial migration (#166)

* init

* upgrade tsconfigs

* shared-db build

* shared-db wip

* transfer getAllSubmissions

* hooked up

* moves to shared-db

* fmt

* update dockerfile

* monorepo

* working build

* migration service

* turbo

* install pnpm

* temp proxy

* no include request headers

* clean up

* proper path

* renaming

* fmt

* update caddyfile

* different strategy

* use route

* fix BACKEND to API

* ignore temp

* temp remove

* back to orig

* turn on auto https

* disable

* route block

* clean up

* configure host

* favicon

* add staging domain

* http:

* set domain adn host

* correct bash

* matching host

* Adds edit feed and image upload (#168)

* adds page

* image upload and edit feed

* update pnpm lock

* CSR

* vercel json

* move

* temp disable auth

* set image

* fix query

* submisison service running

* Migrates submission service, is running (#169)

* init

* wip

* clean up

* feed list clean up

* break up functions

* fix config path

* adds plugins route and integrates with plugin service

* remote curate.config.json

* plugins table

* adds plugin pages

* set type

* fix feed types

* plguin errors

* env injection

* fix queries

* fix migration

* fix migration

* fix migration

* redo migration

* decouples moderation

* fix status

* fix feeds

* hide moderation actions

* adds overwrite script

* migrate timestamps

* better date handling

* fix

* Adds auth (#174)

* adds fastintear auth, init

* auth flow

* fmt

* adds fastintear auth, init

* auth flow

* fmt

* frontend auth

* auth middleware

* feed protection

* fmt

* moderation wip

* update lock

* migration

* moderation actions

* hide moderation actions

* hack

* fix flow

* enable hosted service

* adds user identities and connect platform

* create profile

* ensureUserExists

* set network for staging

* near account id

* auth provider id not null

* init near

* fix monorepo build

* fmt

* user clean up

* update moderation

* switch to crosspost connected

* fix user id and error

* server side

* moderation hooks

* cleaner logs

* Update apps/api/src/services/moderation.service.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update apps/app/src/lib/near.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update apps/app/src/lib/near.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* adds feature flags and moderation service clean up

---------

Co-authored-by: Zeeshan Ahmad <itexpert120@outlook.com>
Co-authored-by: codingshot <45281667+codingshot@users.noreply.github.com>
Co-authored-by: Louis <112561517+louisdevzz@users.noreply.github.com>
Co-authored-by: Muhammad Saad Iqbal <saadiqbal.dev@outlook.com>
Co-authored-by: ethnclark <ethanclark1310@gmail.com>
Co-authored-by: dungpt82 <69756171+dungpt99@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant